package br.com.iswe.gerador.velocity.gerador;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.velocity.VelocityContext;

import br.com.iswe.core.entidades.helper.DateHelper;
import br.com.iswe.core.entidades.helper.DateTimeHelper;
import br.com.iswe.core.entidades.helper.EntityHelper;
import br.com.iswe.core.entidades.helper.GAEHelper;
import br.com.iswe.core.entidades.helper.ManyToOneHelper;
import br.com.iswe.core.entidades.helper.NumericHelper;
import br.com.iswe.core.entidades.helper.PropertyHelper;
import br.com.iswe.core.entidades.helper.SecurityHelper;
import br.com.iswe.core.entidades.helper.TextHelper;
import br.com.iswe.core.entidades.helper.TimeHelper;
import br.com.iswe.core.entidades.helper.UploadHelper;
import br.com.iswe.gerador.velocity.Gerador;
import br.com.iswe.gerador.velocity.helper.GwtHelper;
import br.com.iswe.gerador.velocity.helper.VelocityHelper;
import br.com.iswe.gerador.velocity.info.InfoGerador;
import br.com.iswe.gerador.velocity.patterns.BOPattern;
import br.com.iswe.gerador.velocity.patterns.ControllerPattern;
import br.com.iswe.gerador.velocity.patterns.DAOPattern;
import br.com.iswe.gerador.velocity.patterns.FacadePattern;
import br.com.iswe.gerador.velocity.patterns.GwtPattern;
import br.com.iswe.gerador.velocity.patterns.InfoPattern;
import br.com.iswe.gerador.velocity.patterns.JSFPattern;

public abstract class GeradorBase implements Gerador {

	private static final String PACOTE_ABSTRATOS = "PacoteAbstratos";
    private static final String INFO_GERADOR = "InfoGerador";
    public static final String CHARSET_UTF = "UTF-8";
	
    protected Map<String, Object> parametrosGerador = new HashMap<String, Object>();
    
    public Object getParametro(String nome){
    	return parametrosGerador.get(nome);
    }
    
    public void setParametro(String nome, Object valor){
    	parametrosGerador.put(nome, valor);
    }
    
    public void setParametros(Map<String, Object> parametrosGerador) {
    	this.parametrosGerador = parametrosGerador;
	}
    
	/**
	 * Cria um contexto Velocity com as ferramentas e utilidades necessarias.
	 * 
	 * @return
	 */
	protected VelocityContext buildContext(InfoGerador infoGerador){
		VelocityContext ctx = new VelocityContext();
		
		if(parametrosGerador != null){
			//Caso nao seja nulo o mapa de parametro adiciona os valores ao contexto.
			Iterator<Map.Entry<String, Object>> it = parametrosGerador.entrySet().iterator();
			while(it.hasNext()){
				Map.Entry<String, Object> entry = it.next();
				ctx.put(entry.getKey(), entry.getValue());
			}
		}
		
		//Colocar no contexto os Helpers.
		ctx.put(ManyToOneHelper.HELPER_NAME, new ManyToOneHelper());
		ctx.put(DateHelper.HELPER_NAME, new DateHelper());
		ctx.put(DateTimeHelper.HELPER_NAME, new DateTimeHelper());
		ctx.put(TimeHelper.HELPER_NAME, new TimeHelper());
		ctx.put(NumericHelper.HELPER_NAME, new NumericHelper());
		ctx.put(TextHelper.HELPER_NAME, new TextHelper());
		ctx.put(UploadHelper.HELPER_NAME, new UploadHelper());
		ctx.put(SecurityHelper.HELPER_NAME, new SecurityHelper());
        ctx.put(PropertyHelper.HELPER_NAME, new PropertyHelper());
        ctx.put(EntityHelper.HELPER_NAME, new EntityHelper());
        ctx.put(VelocityHelper.HELPER_NAME, new VelocityHelper());
        ctx.put(GwtHelper.HELPER_NAME, new GwtHelper());
        ctx.put(GAEHelper.HELPER_NAME, new GAEHelper());
		
		//Cria os patterns
		InfoPattern.addPattern(DAOPattern.CONTEXT_NAME, new DAOPattern());
        InfoPattern.addPattern(BOPattern.CONTEXT_NAME, new BOPattern());
        InfoPattern.addPattern(FacadePattern.CONTEXT_NAME, new FacadePattern());
        InfoPattern.addPattern(ControllerPattern.CONTEXT_NAME, new ControllerPattern());
        InfoPattern.addPattern(GwtPattern.CONTEXT_NAME, new GwtPattern());
		InfoPattern.addPattern(JSFPattern.CONTEXT_NAME, new JSFPattern());
		//Os adiciona ao contexto
		ctx.put(InfoPattern.CONTEXT_NAME, new InfoPattern());
		
        //Coloca no contexto o pacote padrao para os objetos abstratos
        ctx.put(PACOTE_ABSTRATOS, infoGerador.getPacoteAbstratos());        
        
		//Coloca as propriedades Base
		ctx.put(INFO_GERADOR, infoGerador);
		
		return ctx;
	}
}
